package org.darkforest.common.mail;

import java.io.File;
import java.security.Security;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.mail.Authenticator;
import javax.mail.Message;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import javax.mail.internet.MimeUtility;

import org.darkforest.common.logger.Logger;
import org.darkforest.common.util.SystemConstant;

public class MailSSLSender {

    private static Session getSession() {
        Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
        final String SSL_FACTORY = "javax.net.ssl.SSLSocketFactory";
        //设置邮件会话参数
        Properties props = new Properties();
        //邮箱的发送服务器地址
        props.setProperty("mail.smtp.host", SystemConstant.HOST.trim());
        props.setProperty("mail.smtp.socketFactory.class", SSL_FACTORY);
        props.setProperty("mail.smtp.socketFactory.fallback", "false");
        //邮箱发送服务器端口,这里设置为465端口
        props.setProperty("mail.smtp.port", SystemConstant.PORT.trim());
        props.setProperty("mail.smtp.socketFactory.port", SystemConstant.PORT.trim());
        props.put("mail.smtp.auth", "true");
        //获取到邮箱会话,利用匿名内部类的方式,将发送者邮箱用户名和密码授权给jvm
        Session session = Session.getDefaultInstance(props, new Authenticator() {
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication(SystemConstant.USERNAME.trim(), SystemConstant.PASSWORD.trim());
            }
        });

        return session;
    }

    /**
     *  发送无附件的邮件
     * @param subject
     * @param content
     * @param sender
     * @param receivers
     */
    public static String sendMail(String subject, String content, String sender, String... receivers) {

        try {
            //通过会话,得到一个邮件,用于发送
            Message message = new MimeMessage(getSession());
            //设置发件人
            message.setFrom(new InternetAddress(sender));
            //设置收件人
            for (int i=0; i<receivers.length; i++) {
                //to为收件人,cc为抄送,bcc为密送
                // msg.setRecipients(Message.RecipientType.TO, InternetAddress.parse(receivers, false));
                message.addRecipients(Message.RecipientType.TO, InternetAddress.parse(receivers[i], false));
            }
            message.setSubject(subject);
            //设置邮件消息
            message.setText(content);
            //设置发送的日期
            message.setSentDate(new Date());
            //调用Transport的send方法去发送邮件
            Transport.send(message);

            return "success";
        } catch (Exception e) {
            e.printStackTrace();
            Logger.error(MailSSLSender.class, "邮件发送失败", e);
            return "fail";
        }
    }

    /**
     *  发送带有附件的邮件
     *
     * @param subject
     * @param content
     * @param sender
     * @param receivers
     * @param cc
     * @param bcc
     * @param imageMap
     * @param filelist
     * @return
     */
    public static String sendMail(String subject, String content, String sender, String[] receivers, String[] cc, String[] bcc,
                                  Map<String,String> imageMap, List<String> filelist) {

        try {
            //通过会话,得到一个邮件,用于发送
            Message message = new MimeMessage(getSession());
            //设置发件人
            message.setFrom(new InternetAddress(sender));
            //设置收件人
            for (int i=0; i<receivers.length; i++) {
                //to为收件人,cc为抄送,bcc为密送
                // msg.setRecipients(Message.RecipientType.TO, InternetAddress.parse(receivers, false));
                message.addRecipients(Message.RecipientType.TO, InternetAddress.parse(receivers[i], false));
            }
            if (cc != null && cc.length > 0) {
                for (int i=0; i<cc.length; i++) {
                    //to为收件人,cc为抄送,bcc为密送
                    message.addRecipients(Message.RecipientType.CC, InternetAddress.parse(cc[i], false));
                }
            }
            if (bcc != null && bcc.length > 0) {
                for (int i=0; i<bcc.length; i++) {
                    //to为收件人,cc为抄送,bcc为密送
                    message.addRecipients(Message.RecipientType.BCC, InternetAddress.parse(bcc[i], false));
                }
            }
            // 设置主题
            message.setSubject(subject);
            //设置邮件消息
            message.setText(content);

            // 附件的设定
            MimeMultipart allMultipart = new MimeMultipart();

            if(imageMap != null && imageMap.size() > 0) {
                // 创建代表邮件正文和附件的各个MimeBodyPart对象
                //创建代表组合Mime消息的MimeMultipart对象，将该MimeMultipart对象保存到MimeBodyPart对象
                MimeBodyPart contentPart = new MimeBodyPart();

                MimeMultipart contentMultipart = new MimeMultipart("related");
                //创建用于保存HTML正文的MimeBodyPart对象，并将它保存到MimeMultipart中
                MimeBodyPart htmlbodypart = new MimeBodyPart();

               // String body ="您的送礼二维码<br/><img src=\"cid:a00000001\"><br/><br/><img src=\"cid:a00000002\">";
                String body ="您的送礼二维码";
                Set<Map.Entry<String, String>> set = imageMap.entrySet();
                for (Iterator iterator = set.iterator(); iterator.hasNext();) {
                    Map.Entry<String, String> entry = (Map.Entry<String, String>) iterator.next();

                    body = body + "<br/><br/><img src='cid:" + entry.getKey() + "'>";
                }

                htmlbodypart.setContent(body,"text/html;charset=UTF-8");
                contentMultipart.addBodyPart(htmlbodypart);

                for (Iterator iterator = set.iterator(); iterator.hasNext();) {
                    Map.Entry<String, String> entry = (Map.Entry<String, String>) iterator.next();

                    //创建用于保存图片的MimeBodyPart对象，并将它保存到MimeMultipart中
                    MimeBodyPart imageBodyPart=new MimeBodyPart();
                    FileDataSource fds=new FileDataSource(entry.getValue());//图片所在的目录的绝对路径

                    imageBodyPart.setDataHandler(new DataHandler(fds));
                    imageBodyPart.setContentID(entry.getKey());   //cid的值
                    imageBodyPart.setFileName(entry.getKey()+".jpg");
                    contentMultipart.addBodyPart(imageBodyPart);
                }

                //将MimeMultipart对象保存到MimeBodyPart对象
                contentPart.setContent(contentMultipart);

                allMultipart.addBodyPart(contentPart);
            }

            // 创建用于组合邮件正文和附件的MimeMultipart对象
            if (filelist != null && filelist.size() > 0) {
                for(int i=0;i < filelist.size();i++){
                    String filename = filelist.get(i);

                    MimeBodyPart attachPart = new MimeBodyPart();
                    FileDataSource fsd = new FileDataSource(filename);
                    attachPart.setDataHandler(new DataHandler(fsd));
                    // 设置附件的文件名（需要编码）
                    attachPart.setFileName(MimeUtility.encodeText(fsd.getName()));
                    allMultipart.addBodyPart(attachPart);
                }
            }

             // Mimemultipart对象中保存的BodyPart对象的个数
            if (allMultipart.getCount() > 0) {
                // 邮件内容
                MimeBodyPart text = new MimeBodyPart();
                text.setContent(content, "text/html;charset=UTF-8");
                allMultipart.addBodyPart(text);
                //有附件资源要定义mixed
                allMultipart.setSubType("mixed");
                // 设置整个邮件的关系（将最终节点作为邮件的内容添加到邮件对象）
                message.setContent(allMultipart);
            }

            //设置发送的日期
            message.setSentDate(new Date());

            message.saveChanges();

            //调用Transport的send方法去发送邮件
            Transport.send(message);
            return "success";
        } catch (Exception e) {
            e.printStackTrace();
            Logger.error(MailSSLSender.class, "邮件发送失败", e);
            return "fail";
        }
    }
}
